package learn_concurrent._6;

import java.util.LinkedList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// 异步模式 生产消费暂停
public class T2 {
	static final Logger logger = LoggerFactory.getLogger(T2.class);

	public static void main(String[] args) throws InterruptedException {
		
		MessageQueue messageQueue = new MessageQueue(2);
		
		for(int i = 0; i < 1; i++) {
			new Thread(() -> {
				Message msg = messageQueue.take();
				logger.info("take a message : {}", msg);
			}, "消费者" + i).start();;
		}
		
		for(int i = 0; i < 3; i++) {
			Message message = new Message(i, "message-" + i);
			new Thread(() -> {
				messageQueue.put(message);
				logger.info("put a message : {}", message);
			}, "生产者" + i).start();;
		}
		
		Thread.sleep(2000);
		logger.info(messageQueue.printList());
	}

}

final class MessageQueue {
	private LinkedList<Message> list = new LinkedList<>();
	private final int capcity;

	public MessageQueue(int capcity) {
		this.capcity = capcity;
	}

	public synchronized Message take() {
		while (list.isEmpty()) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		Message msg = list.pollFirst();
		this.notifyAll();
		return msg;
	}

	public synchronized void put(Message msg) {
		while (list.size() == capcity) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		list.add(msg);
		this.notifyAll();
	}

	public String printList() {
		return list.toString();
	}

}

class Message {
	private final int id;
	private final Object value;

	public Message(int id, Object value) {
		this.id = id;
		this.value = value;
	}

	public int getId() {
		return id;
	}

	public Object getValue() {
		return value;
	}

	@Override
	public String toString() {
		return "Message [id=" + id + ", value=" + value + "]";
	}

}